package com.crazyhat.crazyhat.service.impl;

import java.time.LocalDateTime;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.crazyhat.crazyhat.attribute.TokenPayloadEnum;
import com.crazyhat.crazyhat.dto.PostDTO;
import com.crazyhat.crazyhat.entity.Post;
import com.crazyhat.crazyhat.entity.User;
import com.crazyhat.crazyhat.mapper.PostMapper;
import com.crazyhat.crazyhat.pojo.ContentWithFile;
import com.crazyhat.crazyhat.pojo.PostPublishWithFile;
import com.crazyhat.crazyhat.service.IClubService;
import com.crazyhat.crazyhat.service.IFootprintService;
import com.crazyhat.crazyhat.service.IParticipationService;
import com.crazyhat.crazyhat.service.IPostService;
import com.crazyhat.crazyhat.service.IUserService;
import com.crazyhat.crazyhat.utils.ThreadLocalUtil;
import com.github.yulichang.query.MPJQueryWrapper;

/**
 * <p>
 * 动态 服务实现类
 * </p>
 *
 * @author crazyhat
 * @since 2024-07-05
 */
@Service
public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements IPostService {

    @Autowired
    private PostMapper postMapper;

    @Autowired
    private IClubService clubService;

    @Autowired
    private IParticipationService participationService;

    @Autowired
    private IFootprintService footprintService;

    @Autowired
    private IUserService userService;


    @Override
    public Page<Post> getPostList(Integer clubId,Integer pageNum, Integer pageSize) {

        if (!(clubService.isClubsVisibleForUser(clubId))) {

            return null;
        }

        Map<String,Object> map=ThreadLocalUtil.get();
        Integer studentId=(Integer)map.get(TokenPayloadEnum.StudentId.getValue());

        if (!(clubService.isPostVisibleForUser(clubId, studentId))) {

            //若“动态”对用户不可见
            return null;
        }

        Page<Post> page=new Page<>(pageNum,pageSize);

        QueryWrapper<Post> queryWrapper=new QueryWrapper<>();
        queryWrapper
            .eq("club_id", clubId)
            .orderByDesc("publish_time");

        Page<Post> postList=postMapper.selectPage(page, queryWrapper);;
        return postList;
    }

    @Override
    public Page<PostDTO> getPostPlusList(Integer clubId, Integer pageNum, Integer pageSize) {

        if (!(clubService.isClubsVisibleForUser(clubId))) {

            return null;
        }

        Map<String,Object> map=ThreadLocalUtil.get();
        Integer studentId=(Integer)map.get(TokenPayloadEnum.StudentId.getValue());

        if (!(clubService.isPostVisibleForUser(clubId, studentId))) {

            //若“动态”对用户不可见

            throw new RuntimeException("社区动态不可见");
            // return null;
        }

        Page<PostDTO> page=new Page<>(pageNum,pageSize);

        MPJQueryWrapper<Post> mpjQueryWrapper=new MPJQueryWrapper<>();
        mpjQueryWrapper
            .selectAll(Post.class)
            .select("u.name", "u.avatar_url","u.gender")
            .leftJoin("user u on u.student_id = t.student_id")
            .eq("t.club_id", clubId)
            .orderByDesc("t.publish_time");

        Page<PostDTO> postList=postMapper.selectJoinPage(page, PostDTO.class, mpjQueryWrapper);
        footprintService.addFootprint(clubId);
        return postList;
    }

    @Override
    public boolean deletePost(Integer postId) {

        Map<String,Object> map=ThreadLocalUtil.get();
        Integer studentId=(Integer)map.get("studentId");

        if (hasDeletePower(studentId, postId)) {

            postMapper.deleteById(postId);

            return true;
        } else {
            throw new RuntimeException("无动态删除权限");
        }

        // return false;
    }

    /**
     * 查询用户是否对动态有删除权限
     * @param studentId
     * @param activityId
     * @return
     */
    private boolean hasDeletePower(Integer studentId,Integer postId){

        Post post=postMapper.selectById(postId);

        if (post==null) {
            return false;
        }

        if (post.getStudentId().equals(studentId)) {

            //动态发布人拥有删除动态的权限
            return true;
        }

        Integer clubId=post.getClubId();

        if (participationService.isCommunityManager(clubId)) {

            //社区管理员拥有删除动态的权限
            return true;
        }

        return false;
    }

    @Override
    public PostDTO getPostInfo(Integer postId) {

        if (postId==null) {
            return null;
        }

        Post post=postMapper.selectById(postId);

        if (post==null) {
            return null;
        }

        Map<String,Object> map=ThreadLocalUtil.get();
        Integer studentId=(Integer)map.get(TokenPayloadEnum.StudentId.getValue());

        if (!(clubService.isPostVisibleForUser(post.getClubId(), studentId))) {

            throw new RuntimeException("社区动态不可见");
            //若“动态”对用户不可见
            // return null;
        }

        User user=userService.selectById(post.getStudentId());

        if (user==null) {
            return null;
        }

        PostDTO postDTO=new PostDTO();
        postDTO.initByPost(post);
        postDTO.initByUser(user);

        return postDTO;
    }

    /**
     * 发布动态
     */
    @Override
    public Post createPost(PostPublishWithFile post) {

        if (post==null) {
            return null;
        }

        if (!(clubService.isClubsVisibleForUser(post.getClubId()))) {
            return null;
        }

        //获取当前登录用户ID
        Map<String,Object> map=ThreadLocalUtil.get();
        Integer studentId=(Integer)map.get(TokenPayloadEnum.StudentId.getValue());

        if (!(clubService.hasCommunityContentPublishPower(post.getClubId(), studentId))) {

            //若用户无社区内容发布权限
            throw new RuntimeException("用户无社区内容发布权限");
        }

        Post newPost=new Post();
        newPost.setClubId(post.getClubId());
        newPost.setStudentId(studentId);
        newPost.setPublishTime(LocalDateTime.now());
        newPost.setTitle(post.getTitle());

        //处理动态内容
        ContentWithFile content=new ContentWithFile();
        content.setContent(post.getContent());
        content.setFileList(post.getFileList());

        newPost.setPostContent(content.processAndConvertToJson());

        if (postMapper.insert(newPost)>0) {
            return newPost;
        } else {
            return null;
        }

    }

    /**
     * 更新、修改动态，支持多文件
     */
    @Override
    public Post updatePost(PostPublishWithFile post) {

        if (post==null) {
            return null;
        }

        //获取当前登录用户ID
        Map<String,Object> map=ThreadLocalUtil.get();
        Integer studentId=(Integer)map.get(TokenPayloadEnum.StudentId.getValue());

        Post oldPost=postMapper.selectById(post.getPostId());

        if (oldPost==null || !(oldPost.getStudentId().equals(studentId))) {
            return null;
        }

        oldPost.setTitle(post.getTitle());

        //处理动态内容
        ContentWithFile content=new ContentWithFile();
        content.setContent(post.getContent());
        content.setFileList(post.getFileList());

        oldPost.setPostContent(content.processAndConvertToJson());

        if (postMapper.updateById(oldPost)>0) {
            return oldPost;
        } else {
            return null;
        }
    }

    /**
     * 判断用户是否有动态编辑权限
     */
    @Override
    public boolean hasPostEditPower(Integer postId) {

        //获取当前登录用户ID
        Map<String,Object> map=ThreadLocalUtil.get();
        Integer studentId=(Integer)map.get(TokenPayloadEnum.StudentId.getValue());

        Post oldPost=postMapper.selectById(postId);

        if (oldPost!=null && (oldPost.getStudentId().equals(studentId))) {
            return true;
        }

        return false;
    }
}
